home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / Random2.0 / RandomHist / HistogramView.m < prev    next >
Text File  |  1995-06-12  |  4KB  |  309 lines

  1. //
  2. // HistogramView
  3. //
  4. // Copyright (C) 1992 Contemporary Design Studios.
  5. //
  6.  
  7.  
  8. #import "HistogramView.h"
  9. #import "Random.h"
  10. #import "ElkinsEngine.h"
  11. #import <appkit/Button.h>
  12. #import <dpsclient/wraps.h>    /* for PSxxx functions */
  13. #import <stdlib.h>
  14. #import <math.h>
  15.  
  16.  
  17. #define    RANGEFROM    0.0
  18. #define RANGETO        1.0    
  19. #define NUMBINS        800
  20. #define SCALE        1
  21. #define SCALEBY        2
  22.  
  23.  
  24. @implementation HistogramView
  25.  
  26.  
  27. //
  28. // initFrame:
  29. //
  30.  
  31. - initFrame:(const NXRect *)frameRect
  32. {
  33.     return [self initFrame:frameRect scale:SCALE numBins:NUMBINS];
  34. }
  35.  
  36.  
  37. //
  38. // initFrame:scale:numBins:
  39. //
  40.  
  41. - initFrame:(const NXRect *)frameRect scale:(int)aScale numBins:(int)aNumBins
  42. {
  43.     [super initFrame:frameRect];
  44.     
  45.     randGen = [[Random alloc] initEngineInstance:[[ElkinsEngine alloc] init]];
  46.     
  47.     scaleInval = YES;
  48.     scale = aScale;
  49.     
  50.     numBins = aNumBins;
  51.     
  52.     binFlags = NULL;
  53.     bins = NULL;
  54.     binRects = NULL;
  55.     
  56.     [self allocBins];
  57.     
  58.     return self;
  59. }
  60.  
  61.  
  62. //
  63. // free
  64. //
  65.  
  66. - free
  67. {
  68.     free(binFlags);
  69.     free(bins);
  70.     free(binRects);
  71.     
  72.     return [super free];
  73. }
  74.  
  75.  
  76. //
  77. // allocBins
  78. //
  79.  
  80. - allocBins
  81. {
  82.     int        i;
  83.     
  84.     if(binFlags != NULL) free(binFlags);
  85.     if(bins != NULL) free(bins);
  86.     if(binRects != NULL) free(binRects);
  87.     
  88.     binFlags = (BOOL *)malloc(numBins * sizeof(BOOL));
  89.     bins = (int *)malloc(numBins * sizeof(int));
  90.     binRects = (NXRect *)malloc(numBins * sizeof(NXRect));
  91.     
  92.     binsLeft = 0.0;
  93.     binsBottom = 0.0;
  94.     binWidth = bounds.size.width / numBins;
  95.     binHeightIncrement = bounds.size.height / scale;
  96.     
  97.     for(i = 0; i < numBins; i++) {
  98.         binFlags[i] = NO;
  99.     bins[i] = 0;
  100.     
  101.     binRects[i].origin.x = binsLeft + i * binWidth;
  102.     binRects[i].origin.y = binsBottom;
  103.     binRects[i].size.width = binWidth;
  104.     binRects[i].size.height = 0.0;
  105.     }
  106.     
  107.     return self;
  108. }
  109.  
  110.  
  111. //
  112. // start:
  113. //
  114.  
  115. - start:sender
  116. {
  117.     [startButton setEnabled:NO];
  118.     [stopButton setEnabled:YES];
  119.     
  120.     //
  121.     // Set up modal session:
  122.     //
  123.     
  124.     [NXApp beginModalSession:&mySession for:[self window]];
  125.     
  126.     //
  127.     // Run modal session:
  128.     //
  129.     
  130.     while([NXApp runModalSession:&mySession] != NX_RUNSTOPPED) {
  131.         [self addPoint:[randGen percent]];
  132.     }
  133.     
  134.     return self;
  135. }
  136.  
  137.  
  138. //
  139. // stop:
  140. //
  141.  
  142. - stop:sender
  143. {
  144.     [stopButton setEnabled:NO];
  145.     [startButton setEnabled:YES];
  146.     
  147.     [NXApp stopModal];
  148.     
  149.     return self;
  150. }
  151.  
  152.  
  153. //
  154. // clear:
  155. //
  156.  
  157. - clear:sender
  158. {
  159.     
  160.     scaleInval = YES;
  161.     scale = SCALE;
  162.     
  163.     numBins = NUMBINS;
  164.     
  165.     [self allocBins];
  166.         
  167.     [self display];
  168.     
  169.     return self;
  170. }
  171.  
  172.  
  173. //
  174. // rescaleTo:
  175. //
  176.  
  177. - rescaleTo:(int)newScale
  178. {
  179.     int        i;
  180.     
  181.     if((newScale < 1) || (newScale >= MAXINT)) {
  182.         [self clear:self];
  183.     return self;
  184.     }
  185.     
  186.     scale = newScale;
  187.     
  188.     binHeightIncrement = bounds.size.height / scale;
  189.     
  190.     for(i = 0; i < numBins; i++) {
  191.         binRects[i].size.height = binHeightIncrement * bins[i];
  192.     }
  193.     
  194.     scaleInval = YES;
  195.     
  196.     return self;
  197. }
  198.  
  199.  
  200. //
  201. // addPoint:
  202. //
  203.  
  204. - addPoint:(double)x
  205. {
  206.     int        binNum;
  207.     
  208.     if((x < 0.0) || (x >= 1.0))
  209.     return self;
  210.     
  211.     binNum = floor(numBins * x);
  212.     
  213.     binFlags[binNum] = YES;
  214.     bins[binNum]++;
  215.     
  216.     if(bins[binNum] > scale)
  217.         [self rescaleTo:(scale * SCALEBY)];
  218.     else
  219.         binRects[binNum].size.height += binHeightIncrement;
  220.     
  221.     [self display];
  222.     
  223.     return self;
  224. }
  225.  
  226.  
  227. //
  228. // add:points:
  229. //
  230.  
  231. - add:(int)num points:(double *)array
  232. {
  233.     return self;
  234. }
  235.  
  236.  
  237. //
  238. // takeScaleFrom:
  239. //
  240.  
  241. - takeScaleFrom:aControl
  242. {
  243.     return self;
  244. }
  245.  
  246.  
  247. //
  248. // takeNumBarsFrom:
  249. //
  250.  
  251. - takeNumBarsFrom:aControl
  252. {
  253.     return self;
  254. }
  255.  
  256.  
  257. //
  258. // drawSelf::
  259. //
  260.  
  261. - drawSelf:(const NXRect *)rects :(int)rectCount
  262. {
  263.     int        i;
  264.     
  265.     //
  266.     // Redraw the scale, if necessary:
  267.     //
  268.     
  269.     if(scaleInval) {
  270.     PSsetgray(NX_WHITE);
  271.     NXRectFill(&bounds);
  272.     PSsetgray(NX_BLACK);
  273.     NXFrameRect(&bounds);
  274.     
  275.     //
  276.     // Draw the scale:
  277.     //
  278.     }
  279.     
  280.     //
  281.     // Redraw the bins, as necessary:
  282.     //
  283.     
  284.     for(i = 0; i < numBins; i++) {
  285.         if(binFlags[i] || scaleInval) {
  286.         PSsetgray(NX_BLACK);
  287.         NXRectFill(&binRects[i]);
  288.         
  289.         binFlags[i] = NO;
  290.     }
  291.     }
  292.     
  293.     //
  294.     // Cleanup and return:
  295.     //
  296.     
  297.     scaleInval = NO;
  298.     
  299.     return self;
  300. }
  301.  
  302.  
  303.  
  304. @end
  305.  
  306.  
  307. //
  308. // End of file.
  309. //